/* eslint-disable prefer-template */

const fs = require('fs')
const path = require('path')
const { isString } = require('util')
const { errorLog, warnLog, infoLog, getProjectPath, exit } = require('./common')

// let componentName = process.argv[2]
// if (!componentName) {
//   errorLog('请填写组件名称...')
//   exit()
// }

// 驼峰的组件名称
let HumpComponentName = ''

/**
 * @description: 创建组件
 * @param {String} componentName 组件名称
*/
function createComponent(componentName) {
  // 创建组件文件夹
  fs.mkdirSync(getComponentPath(componentName))
  // index js 数据
  const IndexData = new Uint8Array(Buffer.from(`
import ${HumpComponentName} from '@src/component/publink-ui/${componentName}/${HumpComponentName}'

export default ${HumpComponentName}

`))
  // index.scss 样式
  const IndexScssData = new Uint8Array(Buffer.from(''))
  // 组件数据
  const ComponentData = new Uint8Array(Buffer.from(`
/* scss */
import '@src/component/publink-ui/${componentName}/index.scss'
/* utils */
import { createNamespace, renderSlots } from '@src/util'
import _ from 'lodash'

const [createComponent, bem] = createNamespace('${componentName}')

export default createComponent({
  render (h) {
    const _attrs = _.cloneDeep(this.$attrs)
    const _props = _.cloneDeep(this.$props)
    const AttrsAndProps = _.merge(_attrs || {}, _props || {})
    const attrs = {
      attrs: AttrsAndProps,
      class: bem(),
      on: this.$listeners,
      props: AttrsAndProps,
      slots: this.$slots,
      scopedSlots: this.$scopedSlots
    }
    
    return (
      <publink-${componentName} ref='PublinkElement' {...attrs}>
        { renderSlots(h, this.$slots) }
      </publink-${componentName}>
    )
  }
})

`))
  // 保存文件
  fileSave(`${getComponentPath(componentName)}/index.js`, IndexData)
  fileSave(`${getComponentPath(componentName)}/index.scss`, IndexScssData)
  fileSave(`${getComponentPath(componentName)}/${HumpComponentName}.js`, ComponentData)
}

/**
 * @description: 写入组件索引文件
 * @param {*} componentName 组件名称
*/
function writeComponentIndexFile(componentName) {
  // 文件名称
  const FileName = 'component/publink-ui/index.ts'
  
  try {
    // 组件索引路径
    const ComponentsIndexPath = path.join(__dirname, `../src/${FileName}`)
    // 同步读取组件索引文件
    let componentsIndexText = `${fs.readFileSync(ComponentsIndexPath)}`
    // 占位符
    const ComponentPlaceholder = '/* A Component placeholder */'
    const PlaceholderIndex = componentsIndexText.indexOf(ComponentPlaceholder)
    if (PlaceholderIndex < 0) {
      return errorLog(`请手动修改 ${FileName}`)
    }
    
    // 引入的字符串
    const ImportString = `import ${HumpComponentName} from '@src/component/publink-ui/${componentName}'`
    // 拼接组件引入字符串
    componentsIndexText = (
      componentsIndexText.slice(0, PlaceholderIndex)
        + ImportString
        + '\n'
        + componentsIndexText.slice(PlaceholderIndex)
    )
    // 组件数组索引
    const ComponentArrayPlaceholder = '/* A Array placeholder */'
    const ComponentsArrayIndex = componentsIndexText.indexOf(ComponentArrayPlaceholder)
    if (ComponentsArrayIndex < 0) {
      return errorLog(`请手动修改 ${FileName}`)
    }
    
    // 拼接组件数组字符串
    componentsIndexText = (
      componentsIndexText.slice(0, ComponentsArrayIndex)
        + `${HumpComponentName},`
        + '\n'
        + '  '
        + componentsIndexText.slice(ComponentsArrayIndex)
    )
    // 保存文件
    fileSave(ComponentsIndexPath, componentsIndexText)
    
  } catch (error) {
    errorLog(`修改写入 ${FileName} 出错, ${error}`)
  }
}

/**
 * @description: 保存文件
 * @param {*} path 路径
 * @param {*} fileData 数据
*/
function fileSave(path, fileData) {
  const data = isString(fileData) ? new Uint8Array(Buffer.from(fileData)) : fileData
  
  fs.writeFile(
    path,
    data,
    (err) => {
      if (err) {
        errorLog(`请手动创建修改${path}`)
        throw err
      }
      
      console.log(`${path} 文件保存成功`)
    }
  )
}

/**
 * @description: 字符串转驼峰
 * @param {String} str 字符串
 * @return {String} 转换后的字符串
*/
function stringToHump(str) {
  const reg = /-(\w)/g
  str = str.replace(reg, function ($0, $1) {
    return $1.toUpperCase()
  })
  return `${str[0].toUpperCase()}${str.substr(1)}`
}

/**
 * @description: 获取组件目录
 * @param {String} dirname
 * @return {void}
*/
function getComponentPath(dirname) {
  return path.join(__dirname, '../src/component/publink-ui', dirname)
}

const AllComponentNames = [
  'alert', 'aside', 'autocomplete', 'avatar',
  'backtop', 'badge', 'breadcrumb', 'breadcrumb-item',
  'button', 'button-group', 'calendar', 'card',
  'carousel', 'carousel-item', 'cascader', 'cascader-panel',
  'checkbox', 'checkbox-button', 'checkbox-group', 'col',
  'collapse', 'collapse-item', 'color-picker', 'container',
  'date-picker', 'dialog', 'divider', 'drawer',
  'dropdown', 'dropdown-item', 'dropdown-menu', 'footer',
  'form', 'form-item', 'header', 'icon',
  'image', 'infinite-scroll', 'input', 'input-number',
  'link', 'loading', 'main', 'menu',
  'menu-item', 'menu-item-group', 'message', 'message-box',
  'notification', 'option', 'option-group', 'page-header',
  'pagination', 'popconfirm', 'popover', 'progress',
  'radio', 'radio-button', 'radio-group', 'rate',
  'row', 'scrollbar', 'select', 'slider',
  'spinner', 'step', 'steps', 'submenu',
  'switch', 'tab-pane', 'table', 'table-column',
  'tabs', 'tag', 'time-picker',
  'time-select', 'timeline', 'timeline-item', 'tooltip',
  'transfer', 'transitions', 'tree', 'upload'
]

AllComponentNames.forEach(name => {
  HumpComponentName = stringToHump(name)
  createComponent(name)
  writeComponentIndexFile(name)
})